// 云函数入口文件
const cloud = require('wx-server-sdk');
//将xml转化为json包
const xml2js = require('xml2js');
//http访问包
var superagent = require('superagent');
//md5加密包
var md5 = require('md5-node');
//requset包
const request = require('request')

//安装xml向json的转化包


//*******************************新建【WeXinPay】类****************************
const Wexin = {
  APPID: 'wx553fbf4a5b9c4d73', //微信公众号身份的唯一标识
  APPSECRET: '5280cac89916b7810922e63dc70278ac',//微信公众号secret
  MCHID: '1513477211',//商户id
  KEY: 'FamilyYoghourtWeAreFamily8888888',//商户支付密钥Key
  APPURL: 'http://192.168.1.112:8080/familyService/',//回调通知接口
  TRADETYPE: 'JSAPI',//交易类型
  BODY: '伐木累-炒酸奶'//商品类型信息
};

class weixinPayOrderQuery {
  //=======【基本信息设置】=====================================
  //【微信订单查询】的构造函数
  constructor(orderId) {
    this.orderId = orderId; //订单编号
  }
  // 查询
  query() {
    return this.getQueryResult();
  }
  //对【微信订单查询】接口返回的数据进行处理
  /*
  返回的数据格式如下所示:

  */

  getQueryResult(json) {
    //[订单查询接口]通信标识 和 返回结果标识
    if (json['return_code'] == 'SUCCESS' && json['result_code'] == 'SUCCESS' && json['trade_state'] == 'SUCCESS') {
      return 'SUCCESS'
    } else {
      return 'FAIL'
    }
  }
  /*
   * 订单查询API 请求参数构造 (返回xml格式)
   */
  generateRequestParameters() {
    let that = this;
    let parameters = [];
    parameters['appid'] = Wexin.APPID; //小程序APPID
    parameters['mch_id'] = Wexin.MCHID;//商户id
    parameters['nonce_str'] = this.createNoncestr();//随机字符串
    parameters['out_trade_no'] = this.orderId;//商户订单编号
    parameters['sign'] = this.getSign(parameters);
    let xmlData = this.arrayToXml(parameters);
    return xmlData;
  }
  //数组转字符串方法
  // 这种方式可以遍历关联数组中的名称 
  arrayToXml(arr) {
    let xml = "<xml>";
    for (var key in arr) {
      var val = arr[key];
      xml += "<" + key + ">" + val + "</" + key + ">";
      //判断val值是否为字符串
      // if ((typeof val == 'string') && val.constructor == String) {
      //   xml += "<" + key + "><![CDATA[" + val + "]]></" + key + ">";    
      // } else {
      xml += "<" + key + ">" + val + "</" + key + ">";
      // }
    }
    xml += "</xml>";
    return xml;
  }

  //------------------------------将xml数据转化为json数据
  xmlToArray(xml) {
    //xml2js默认会把子子节点的值变为一个数组, explicitArray设置为false
    var xmlParser = new xml2js.Parser({ explicitArray: false, ignoreAttrs: true })
    let array_data = null;
    // xml -> json
    xmlParser.parseString(xml, function (err, result) {    //将返回的结果再次格式化
      array_data = result
    });
    return array_data;
  }
  /*
   * 对一个关联数组，依据key值进行升序排序
   */
  keySort(arr) {
    let keyArr = [];
    for (var key in arr) {
      keyArr.push(key)
    }
    keyArr.sort();//sort不提供参数，默认照字符编码的顺序进行升序排序
    let newArr = [];
    for (let i = 0; i < keyArr.length; i++) {
      let tempKey = keyArr[i]; //获取当前的key值
      newArr[tempKey] = arr[tempKey]
    }
    return newArr;
  }
  /*
   * md5加密
   */
  convert2MD5(str) {
    var str = md5(str)
    return str.toUpperCase();
  }
  /*
   * 对要发送到微信统一下单接口的数据进行签名
stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注：key为商户平台设置的密钥key
sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" //注：MD5签名方式
sign=hash_hmac("sha256",stringSignTemp,key).toUpperCase()="6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6" //注：HMAC-SHA256签名方式
   */
  getSign(arr) {

    let Parameters = [];
    for (var key in arr) {
      Parameters[key] = arr[key];
    }
    //签名步骤一：按照键名对关联数组进行升序排序
    Parameters = this.keySort(Parameters);
    let str = '';
    str = this.formatBizQueryParaMap(Parameters, false);
    //签名步骤二：在string后加入KEY
    str = str + "&key=" + Wexin.KEY;
    //签名步骤三：MD5加密
    str = this.convert2MD5(str);
    //签名步骤四：所有字符转为大写
    let result = str.toUpperCase();
    return result;
  }
  /*
   *排序并格式化参数方法，签名时需要使用
   */
  formatBizQueryParaMap(paraMap) {
    let buff = "";
    this.keySort(paraMap);
    for (var key in paraMap) {
      buff += key + "=" + paraMap[key] + "&";
    }
    let reqPar = '';
    if (buff.length > 0) {
      reqPar = buff.substr(0, buff.length - 1)
    }
    return reqPar;
  }
  //获取指定区间范围随机数，包括lowerValue和upperValue
  randomFrom(lowerValue, upperValue) {
    return Math.floor(Math.random() * (upperValue - lowerValue + 1) + lowerValue);
  }
  /*
   * 生成随机字符串方法
   */
  createNoncestr(length = 32) {
    let chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    let str = "";
    for (let i = 0; i < length; i++) {
      str += chars.substr(this.randomFrom(0, chars.length - 1), 1)
    }
    return str;
  }
}

//*****************************************************************************
// 云函数入口函数
exports.main = async (event, context) => {

  let orderId = event.orderId; //传入订单号

  //新建支付类对象
  let orderQuery = new weixinPayOrderQuery(orderId);

  let xml = orderQuery.generateRequestParameters()//获取[订单查询]接口的参数(xml)格式

  //新建promise对象，发起http统一下单请求
  return new Promise((resolve, reject) => {
    try {
      request.post(
        {
          url: 'https://api.mch.weixin.qq.com/pay/orderquery',
          method: "POST",
          json: true,
          headers: {
            "content-type": "application/x-www-form-urlencoded",
            "Accept-Charset": "utf-8"
          },
          body: xml
        },
        function (error, response, body) {
          if (!error && response.statusCode == 200) {
            let apiParas = orderQuery.xmlToArray(body)
            let paras = apiParas.xml
            return resolve(orderQuery.getQueryResult(paras))
          }
          else {
            return reject(err)
          }
        })
    } catch (e) {
      return reject(err)
    }
  })
}